using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Work.API.Applications.Write.Commands;
using Work.Domain.DrugManage;
using Work.ErrorCode;
using Work.Infrastructure.Interfaces;

namespace Work.API.Applications.Write.CommandHandlers
{
    /// <summary>
    /// 创建药品处理器（用于药品入库模块 - 首次入库）
    /// 业务逻辑：
    /// 1. 检查药品是否已存在（根据药品名称）
    /// 2. 如果不存在，创建新药品记录
    /// 3. 创建入库记录
    /// 4. 更新库存数量
    /// </summary>
    public class CreateDrugCommandHandler : IRequestHandler<CreateDrugCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<Drug> _drugRepo;
        private readonly IBaseRepository<DrugInbound> _inboundRepo;
        private readonly IMapper _mapper;

        public CreateDrugCommandHandler(
            IBaseRepository<Drug> drugRepo,
            IBaseRepository<DrugInbound> inboundRepo,
            IMapper mapper)
        {
            _drugRepo = drugRepo;
            _inboundRepo = inboundRepo;
            _mapper = mapper;
        }

        public async Task<ApiResult<int>> Handle(CreateDrugCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<int>();

            try
            {
                // 1. 检查药品是否已存在（根据药品名称）
                var existingDrug = await _drugRepo.GetAll()
                    .Where(d => d.DrugName == request.DrugName && d.IsEnabled)
                    .FirstOrDefaultAsync(cancellationToken);

                if (existingDrug != null)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = $"药品'{request.DrugName}'已存在，请使用'药品入库'功能增加库存";
                    result.Data = 0;
                    return result;
                }

                // 2. 检查入库数量是否在库存上下限范围内
                if (request.Quantity < request.InventoryLowerLimit)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = $"入库数量（{request.Quantity}）小于库存下限（{request.InventoryLowerLimit}），不能入库。请调整入库数量，使其大于等于库存下限。";
                    result.Data = 0;
                    return result;
                }

                if (request.Quantity > request.InventoryUpperLimit)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = $"入库数量（{request.Quantity}）大于库存上限（{request.InventoryUpperLimit}），不能入库。请调整入库数量，使其小于等于库存上限。";
                    result.Data = 0;
                    return result;
                }

                // 3. 创建新药品记录
                var drug = new Drug
                {
                    DrugName = request.DrugName,
                    DrugType = request.DrugType,
                    CostName = request.CostName,
                    DosageForm = request.DosageForm,
                    Specification = request.Specification,
                    PurchasePrice = request.PurchasePrice,
                    SellingPrice = request.SellingPrice,
                    Inventory = request.Quantity, // 首次入库的数量作为初始库存
                    InventoryUpperLimit = request.InventoryUpperLimit,
                    InventoryLowerLimit = request.InventoryLowerLimit,
                    Efficacy = request.Efficacy,
                    CreateTime = DateTime.Now,
                    CreateBy = request.Operator,
                    IsEnabled = true
                };

                var drugRows = await _drugRepo.AddAsync(drug);

                if (drugRows <= 0)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "药品创建失败";
                    result.Data = 0;
                    return result;
                }

                // 4. 创建入库记录
                var inbound = new DrugInbound
                {
                    DrugId = drug.DrugId,
                    Quantity = request.Quantity,
                    UnitPrice = request.PurchasePrice, // 首次入库使用进价
                    TotalAmount = request.PurchasePrice * request.Quantity,
                    ProductionDate = request.ProductionDate,
                    ExpirationDate = request.ExpirationDate,
                    BatchNumber = request.BatchNumber,
                    Supplier = request.Supplier,
                    InboundDate = DateTime.Now,
                    Operator = request.Operator,
                    Remarks = request.Remarks,
                    CreateTime = DateTime.Now
                };

                var inboundRows = await _inboundRepo.AddAsync(inbound);

                if (inboundRows > 0)
                {
                    result.Code = ApiEnum.成功;
                    result.Message = "药品创建成功，入库记录已创建";
                    result.Data = drug.DrugId;
                }
                else
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "药品创建成功，但入库记录创建失败";
                    result.Data = drug.DrugId;
                }
            }
            catch (Exception ex)
            {
                result.Code = ApiEnum.失败;
                result.Message = $"创建失败：{ex.Message}";
                result.Data = 0;
            }

            return result;
        }
    }
}

